package org.example.forum.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.session.StandardSession;
import org.example.forum.common.AppResult;
import org.example.forum.common.ResultCode;
import org.example.forum.config.AppConfig;
import org.example.forum.model.User;
import org.example.forum.services.IUserService;
import org.example.forum.utils.MD5Utils;
import org.example.forum.utils.StringUtil;
import org.example.forum.utils.UUIDUtil;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "用户接口") //api说明
public class UserController {
    @Resource
    private IUserService userService;

    /**
     *
     * @param username 用户名
     * @param nickname 用户昵称
     * @param password 密码
     * @param passwordRepeat 确认密码
     * @return
     */
    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public AppResult register(@Parameter(description = "用户名") @RequestParam("username") @NonNull String username,
                              @Parameter(ref = "用户昵称") @RequestParam("nickname") @NonNull String nickname,
                              @Parameter(ref = "密码") @RequestParam("password") @NonNull String password,
                              @Parameter(ref = "确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat) {

//        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(nickname)
//                || StringUtil.isEmpty(password) || StringUtil.isEmpty(passwordRepeat)) {
//            //校验失败返回错误信息
//            return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
//        }
        //校验两次密码输入是否相同
        if (!password.equals(passwordRepeat)) {
            log.warn(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        //准备数据
        User user = new User();
        user.setUsername(username);
        user.setNickname(nickname);
        //处理密码
        //1.生成盐
        String salt = UUIDUtil.getUUID_32();
        //2.生成密码的密文
        String encryptPassword = MD5Utils.md5Salt(password, salt);
        //3.设置盐和密文
        user.setPassword(encryptPassword);
        user.setSalt(salt);

        //调用Service层
        userService.createNormalUser(user);
        return AppResult.success();
    }

    /**
     * 用户登录
     * @param username 用户名
     * @param password 密码
     */
    @Operation(summary = "用户登录")
    @PostMapping("/login")
    public AppResult login(HttpServletRequest request,
                           @Parameter(ref = "用户名") @RequestParam("username") @NonNull String username,
                           @Parameter(ref = "密码") @RequestParam("password") @NonNull String password) {
        //1、调用Service中的登录方法，返回User对象
        User user = userService.login(username, password);
        if (user == null) {
            log.warn(ResultCode.FAILED_LOGIN.toString());
            return AppResult.failed(ResultCode.FAILED_LOGIN);
        }
        //2、如果登录成功，把User对象设置到Session作用域中(true 表示没有Session对象时创建一个新的
        HttpSession session = request.getSession(true);
        session.setAttribute(AppConfig.USER_SESSION,user);
        //3、返回结果
        return AppResult.success();
    }

    /**
     * @param request
     * @param id
     * @return
     */
    @Operation(summary = "获取用户信息")
    @GetMapping("/info")
    public AppResult<User> getUserInfo(HttpServletRequest request,
                                       @Parameter(ref = "用户id") @RequestParam(value = "id",required = false) Long id) {
        User user = null;
        if (id == null) {
            //1、如果id为空，从session中获取当前登录的用户信息
            //获取session 指定为false，如果没有session不创建
            HttpSession session = request.getSession(false);

            //---------------配置了拦截器后，以下代码就不需要了---------------
            //判断session和用户信息是否有效
//            if (session == null || session.getAttribute(AppConfig.USER_SESSION) == null) {
//                //表示用户未登录
//                return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
//            }


            //校验通过从session中获取用户信息
            user = (User)session.getAttribute(AppConfig.USER_SESSION);
        } else {
            //2、如果id不为空，根据id从数据库中查询用户信息
            user = userService.selectById(id);
        }
        //判断user是否为空
        if (user == null) {
            return AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        //返回正常结果
        return AppResult.success(user);
    }

    @Operation(summary = "退出登录")
    @GetMapping("/logout")
    public AppResult logout(HttpServletRequest request) {
        //获取session对象
        HttpSession session = request.getSession(false);
        //判断session是否有效
        if (session != null) {
            log.info("用户登录状态下 退出成功");
            //表示用户处于登录状态，直接销毁session
            session.invalidate();
        }
        return AppResult.success("退出成功");
    }

    /**
     * 修改个人信息
     * @param username 用户名
     * @param nickname 昵称
     * @param gender 性别
     * @param email 邮箱
     * @param phoneNum 电话号码
     * @param remark 个人简介
     * @return AppResult
     */
    @PostMapping("/modifyInfo")
    @Operation(summary = "修改个人信息")
    public AppResult modifyInfo(HttpServletRequest request,
                                @Parameter(ref = "用户名")@RequestParam(value = "username",required = false) String username,
                                @Parameter(ref = "昵称")@RequestParam(value = "nickname",required = false)String nickname,
                                @Parameter(ref = "性别")@RequestParam(value = "gender",required = false)Byte gender,
                                @Parameter(ref = "邮箱")@RequestParam(value = "email",required = false)String email,
                                @Parameter(ref = "电话号码")@RequestParam(value = "phoneNum",required = false)String phoneNum,
                                @Parameter(ref = "个人简介")@RequestParam(value = "remark",required = false)String remark){
        //1、接收参数

        //2、对参数做非空校验（全部为空则返回错误描述
        if (StringUtil.isEmpty(username) && StringUtil.isEmpty(nickname) && gender == null &&
                StringUtil.isEmpty(email) && StringUtil.isEmpty(phoneNum) && StringUtil.isEmpty(remark)) {
            //返回错误信息
            return AppResult.failed("请输入要修改的内容");
        }
        //3、封装对象
        User updateUser = new User();
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        updateUser.setId(user.getId());
        updateUser.setUsername(username);
        updateUser.setNickname(nickname);
        updateUser.setGender(gender);
        updateUser.setEmail(email);
        updateUser.setPhoneNum(phoneNum);
        updateUser.setRemark(remark);

        //4、调用Service中的方法
        userService.modifyInfo(updateUser);

        //5、查询最新的用户信息
        user = userService.selectById(user.getId());
        //6、将最新的用户信息设置到session中
        session.setAttribute(AppConfig.USER_SESSION,user);
        //7、返回最新结果
        return AppResult.success(user);
    }

    @PostMapping("/modifyPwd")
    @Operation(summary = "修改密码")
    public AppResult modifyPassword(HttpServletRequest request,
                                    @Parameter(ref = "原密码")@RequestParam("oldPassword") String oldPassword,
                                    @Parameter(ref = "新密码")@RequestParam("newPassword") String newPassword,
                                    @Parameter(ref = "确认密码")@RequestParam("passwordRepeat") String passwordRepeat) {
        //1、校验新密码和原密码是否相同
        if (!passwordRepeat.equals(newPassword)) {
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        //2、获取当前登录用户信息
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        //3、调用service
        userService.modifyPassword(user.getId(), newPassword, oldPassword);
        //4、销毁session实现强制重新登录
        if (session != null) {
            session.invalidate();
        }
        //返回结果
        return AppResult.success();
    }
}
